--编写者：alt
--功能介绍：buff模板 增加buff
--使用方法：增删bufflist内的内容即可 使用的时候ent:AddDebuff("buff_examplebuff", "buff_examplebuff")
--ent:AddDebuff("buff_examplebuff", "buff_examplebuff")
--examplebuff文件改名xxx_buffs
local bufflist = {
    buff_examplebuff = {
        duration = 60,
        attachstring = "",
        deteachstring = "",
        onattachedfn = function(inst, target)
            SpawnPrefab("battlesong_instant_taunt_fx").Transform:SetPosition(target.Transform:GetWorldPosition())
        end,
        onextendedfn = function(inst, target)
            SpawnPrefab("battlesong_instant_taunt_fx").Transform:SetPosition(target.Transform:GetWorldPosition())
        end,
        ondetachedfn = function(inst, target)

        end,
        priority = 0,
    },
}
-------------------------------------------------------------------------
----------------------- Prefab building functions -----------------------
-------------------------------------------------------------------------

local function OnTimerDone(inst, data)
    if data.name == "buffover" then
        inst.components.debuff:Stop()
    end
end

local function MakeBuff(name, onattachedfn, onextendedfn, ondetachedfn, duration, priority, prefabs, data)
    data = data or {}
    local attachstring = data.attachstring
    local deteachstring = data.deteachstring
    STRINGS.CHARACTERS.GENERIC["ANNOUNCE_ATTACH_" .. string.upper(name)] = attachstring
    STRINGS.CHARACTERS.GENERIC["ANNOUNCE_DETACH_" .. string.upper(name)] = deteachstring
    local ATTACH_BUFF_DATA = {
        buff = "ANNOUNCE_ATTACH_" .. string.upper(name),
        priority = priority
    }
    local DETACH_BUFF_DATA = {
        buff = "ANNOUNCE_DETACH_" .. string.upper(name),
        priority = priority
    }

    local function OnAttached(inst, target, followsymbol, followoffset, buffdata, buffer)
        inst.entity:SetParent(target.entity)
        inst.Transform:SetPosition(0, 0, 0) --in case of loading
        inst:ListenForEvent("death", function()
            inst.components.debuff:Stop()
        end, target)
        if attachstring then
            target:PushEvent("foodbuffattached", ATTACH_BUFF_DATA)
        end
        if onattachedfn ~= nil then
            onattachedfn(inst, target, followsymbol, followoffset, buffdata, buffer)
        end
    end

    local function OnExtended(inst, target, followsymbol, followoffset, buffdata, buffer)
        inst.components.timer:StopTimer("buffover")
        inst.components.timer:StartTimer("buffover", duration)

        if onextendedfn ~= nil then
            onextendedfn(inst, target, followsymbol, followoffset, buffdata, buffer)
        end
    end

    local function OnDetached(inst, target)
        if ondetachedfn ~= nil then
            ondetachedfn(inst, target)
        end
        if deteachstring then
            target:PushEvent("foodbuffdetached", DETACH_BUFF_DATA)
        end
        inst:Remove()
    end

    local function fn()
        local inst = CreateEntity()

        if not TheWorld.ismastersim then
            --Not meant for client!
            inst:DoTaskInTime(0, inst.Remove)
            return inst
        end

        inst.entity:AddTransform()

        --[[Non-networked entity]]
        --inst.entity:SetCanSleep(false)
        inst.entity:Hide()
        inst.persists = false

        inst:AddTag("CLASSIFIED")

        inst:AddComponent("debuff")
        inst.components.debuff:SetAttachedFn(OnAttached)
        inst.components.debuff:SetDetachedFn(OnDetached)
        inst.components.debuff:SetExtendedFn(OnExtended)
        inst.components.debuff.keepondespawn = true

        inst:AddComponent("timer")
        inst.components.timer:StartTimer("buffover", duration)
        inst:ListenForEvent("timerdone", OnTimerDone)

        return inst
    end

    return Prefab(name, fn, nil, prefabs)
end
local buffs = {}
for k, v in pairs(bufflist) do
    table.insert(buffs,
        MakeBuff(k, v.onattachedfn, v.onextendedfn, v.ondetachedfn, v.duration, (v.priority or 0), v.prefabs, v))
end
return unpack(buffs)
